package com.inwavetech.os.sync.jsonparser;

import android.text.Html;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;

/**
 * base class to performs data validation and clean* for Os and Product json's
 *
 * * data clean = correctly data format for a specific use
 */
abstract public class BaseJsonParser {

    // used to validate and clean a value
    protected HashMap<String, JsonCleaner> cleaners = new HashMap<String, JsonCleaner>();
    // list of required json entries
    protected ArrayList<String> expectedKeys = new ArrayList<String>();

    public BaseJsonParser() {
        expectedKeys.add("id");

        cleaners.put("id", new JsonCleaner() {
            @Override
            public Object validateAndClean(String receivedValue) {
                String value = (String) receivedValue;

                if (!value.trim().isEmpty()) {
                    return value;
                }

                return false;
            }
        });
    }

    public final void parse(JSONObject aJson, Object anObject) throws InvalidEntityJsonException, JSONException {
        boolean hasErrors = false;
        HashMap<String, Object> cleanedValues = new HashMap<String, Object>();
        InvalidEntityJsonException e = new InvalidEntityJsonException();

        for (String keyname: expectedKeys) {
            Object value = validateAndClean(aJson, keyname);

            if (false != value) {
                cleanedValues.put(keyname, value);
            } else {
                hasErrors = true;
                e.addError(keyname);
            }
        }

        if (hasErrors) {
            throw e;
        }

        populate(cleanedValues, anObject);
    }

    public final Object validateAndClean(JSONObject aJson, String keyname) throws JSONException {
        // check the field existence
        if (!aJson.has(keyname)) {
            return false;
        }

        // check for a configured cleaner
        if (cleaners.containsKey(keyname)) {
            // validate and clean the value
            return cleaners.get(keyname).validateAndClean(aJson.getString(keyname));
        }

        // no configured cleaner. perform the basic clean operation
        return Html.fromHtml(aJson.getString(keyname)).toString();
    }

    protected abstract void populate(HashMap<String, Object> cleanedValues, Object anObject);
}
